home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / util / misc / VMM_src.lha / VMM / tools / VMMUsage.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-16  |  10.3 KB  |  456 lines

  1. #ifndef MAKE_ID
  2. #define MAKE_ID(a,b,c,d) ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))
  3. #endif
  4.  
  5. #ifdef _DCC
  6. #define __inline
  7. #endif
  8.  
  9. #include <string.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <clib/utility_protos.h>
  13. #include "VMMUsage.h"
  14. #ifdef __GNUC__
  15. #include "../include/VMM_stat.h"
  16. #include <inline/muimaster.h>
  17. #else
  18. #include "/include/VMM_stat.h"
  19. #endif
  20.  
  21. extern void *InitTimer (int, UWORD *);
  22. extern void CloseTimer (void *);
  23. extern BOOL AddTimedFunction (void *, ULONG secs, ULONG micros, void (*function) ());
  24. extern void HandleTimerReturn (void *);
  25.  
  26. struct Hook DisplayHook;
  27. struct Hook DestructHook;
  28. struct ObjApp *ObjApp;
  29. void *TimerData;
  30. struct VMUsageMsg *UsageMsg;
  31. LONG VMSignal;
  32. BOOL ListEmpty = TRUE;
  33.  
  34. struct Library *MUIMasterBase;
  35. struct Library *UtilityBase;
  36. UWORD TimerSignal;
  37.  
  38. #ifdef __GNUC__
  39. extern void CallHook_C (void);
  40. #endif
  41.  
  42. /******************************************************************************/
  43.  
  44. #ifdef __GNUC__
  45. static LONG DisplayElem (struct Hook *hook, struct TaskVMUsage *te, char **array )
  46. #else
  47. static __saveds __asm LONG DisplayElem (register __a1 struct TaskVMUsage *te,
  48.                                         register __a2 char **array)
  49. #endif
  50.  
  51. {
  52. static char buf [50];
  53.  
  54. *array++ = te->vu_Node.ln_Name;
  55.  
  56. sprintf (buf, "%ld", te->VMInUse);
  57. *array++ = buf;
  58.  
  59. return (0);
  60. }
  61.  
  62. /******************************************************************************/
  63.  
  64. #ifdef __GNUC__
  65. static void DestructElem (struct Hook *hook, struct TaskVMUsage *te, int dummy)
  66. #else
  67. static __saveds __asm void DestructElem (register __a1 struct TaskVMUsage *te)
  68. #endif
  69.  
  70. {
  71. FreeMem (te, te->FreeSize);
  72. }
  73.  
  74. /******************************************************************************/
  75.  
  76. struct ObjApp * CreateApp(void)
  77. {
  78.     struct ObjApp * Object;
  79.  
  80.     APTR    GROUP_ROOT_0, TX_UpdateTime, TX_Title;
  81.  
  82.     if (!(Object = AllocVec(sizeof(struct ObjApp), MEMF_PUBLIC|MEMF_CLEAR)))
  83.         return(NULL);
  84.  
  85. #ifdef __GNUC__
  86.      DisplayHook.h_Entry = (HOOKFUNC)CallHook_C;
  87.      DisplayHook.h_SubEntry = (HOOKFUNC)DisplayElem;
  88.      DestructHook.h_Entry = (HOOKFUNC)CallHook_C;
  89.      DestructHook.h_SubEntry = (HOOKFUNC)DestructElem;
  90. #else
  91.      DisplayHook.h_Entry = (HOOKFUNC)DisplayElem;
  92.      DestructHook.h_Entry = (HOOKFUNC)DestructElem;
  93. #endif
  94.  
  95.     Object->STR_TX_UpdateTime = "\033cUpdate frequency";
  96.     Object->STR_TX_Frequency = NULL;
  97.  
  98.      TX_Title = TextObject,
  99.         MUIA_Text_Contents, "Tasks using VM",
  100.         MUIA_Text_PreParse, "\033c",
  101.      End;
  102.  
  103.     Object->LV_TaskList = ListObject,
  104.         MUIA_Frame, MUIV_Frame_ReadList,
  105.         MUIA_List_Format, "MINWIDTH=20 MAXWIDTH=100,PREPARSE=\33r",
  106.         MUIA_List_DisplayHook, &DisplayHook,
  107.         MUIA_List_DestructHook, &DestructHook,
  108.     End;
  109.  
  110.     Object->LV_TaskList = ListviewObject,
  111.         MUIA_Listview_List, Object->LV_TaskList,
  112.         MUIA_Listview_Input, FALSE,
  113.         MUIA_Weight, 1000,
  114.     End;
  115.  
  116.     TX_UpdateTime = TextObject,
  117.         MUIA_Background, MUII_WindowBack,
  118.         MUIA_Text_Contents, Object->STR_TX_UpdateTime,
  119.     End;
  120.  
  121.     Object->SL_UpdateTime = SliderObject,
  122.         MUIA_Weight, 0,
  123.         MUIA_Slider_Min, 1,
  124.         MUIA_Slider_Max, 100,
  125.         MUIA_Slider_Quiet, TRUE,
  126.         MUIA_Slider_Level, 10,
  127.     End;
  128.  
  129.     Object->TX_Frequency = TextObject,
  130.         MUIA_Background, MUII_WindowBack,
  131.         MUIA_Text_Contents, Object->STR_TX_Frequency,
  132.         MUIA_Text_PreParse, "\033c",
  133.         MUIA_Text_Contents, "10/10 s",
  134.         MUIA_Text_SetMin, TRUE,
  135.     End;
  136.  
  137.     GROUP_ROOT_0 = GroupObject,
  138.          Child, TX_Title,
  139.         Child, Object->LV_TaskList,
  140.         Child, TX_UpdateTime,
  141.         Child, Object->SL_UpdateTime,
  142.         Child, Object->TX_Frequency,
  143.     End;
  144.  
  145.     Object->WI_Usage = WindowObject,
  146.         MUIA_Window_Title, "VM Usage",
  147.         MUIA_Window_ID, MAKE_ID('0', 'W', 'I', 'N'),
  148.         WindowContents, GROUP_ROOT_0,
  149.     End;
  150.  
  151.     Object->App = ApplicationObject,
  152.         MUIA_Application_Author, "Martin Apel",
  153.         MUIA_Application_Base, "VMU",
  154.         MUIA_Application_Title, "VMUsage",
  155.         MUIA_Application_Version, "$VER: VMUsage 1.1 (15.12.95)",
  156.         MUIA_Application_Copyright, "Martin Apel",
  157.         MUIA_Application_Description, "Vm usage display",
  158.         SubWindow, Object->WI_Usage,
  159.     End;
  160.  
  161.  
  162.     if (!Object->App)
  163.     {
  164.         FreeVec(Object);
  165.         return(NULL);
  166.     }
  167.  
  168.     DoMethod(Object->SL_UpdateTime,
  169.         MUIM_Notify, MUIA_Slider_Level, MUIV_EveryTime,
  170.         Object->TX_Frequency,
  171.         4,
  172.         MUIM_SetAsString, MUIA_Text_Contents, "%2ld/10 s", MUIV_TriggerValue
  173.         );
  174.  
  175.      DoMethod (Object->WI_Usage,
  176.           MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
  177.         Object->App,
  178.         2,
  179.         MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit
  180.         );
  181.           
  182.     DoMethod(Object->WI_Usage,
  183.         MUIM_Window_SetCycleChain, Object->LV_TaskList,
  184.         Object->SL_UpdateTime,
  185.         0
  186.         );
  187.  
  188.     set(Object->WI_Usage,
  189.         MUIA_Window_Open, TRUE
  190.         );
  191.  
  192.  
  193.     return(Object);
  194. }
  195.  
  196. /******************************************************************************/
  197.  
  198. void DisposeApp(struct ObjApp * Object)
  199. {
  200.     MUI_DisposeObject(Object->App);
  201.     FreeVec(Object);
  202. }
  203.  
  204. /******************************************************************************/
  205.  
  206. void SortList (struct List *list)
  207.  
  208. {
  209. /* Sort a list by ln_Name. */
  210.  
  211. struct Node *tmp1,
  212.             *tmp2;
  213. struct List TmpList;
  214.  
  215. NewList (&TmpList);
  216.  
  217. while (list->lh_Head->ln_Succ != NULL)    /* Not empty */
  218.   {
  219.   tmp1 = list->lh_Head;
  220.   for (tmp2 = tmp1->ln_Succ; tmp2->ln_Succ != NULL; tmp2 = tmp2->ln_Succ)
  221.     {
  222.     if (Stricmp (tmp1->ln_Name, tmp2->ln_Name) < 0)
  223.       tmp1 = tmp2;
  224.     }
  225.   Remove (tmp1);
  226.   AddHead (&TmpList, tmp1);
  227.   }
  228.  
  229. while (TmpList.lh_Head->ln_Succ != NULL)
  230.   {
  231.   tmp1 = RemHead (&TmpList);
  232.   AddTail (list, tmp1);
  233.   }
  234. }
  235.  
  236. /******************************************************************************/
  237.  
  238. struct List *GetListFromVMM (void)
  239.  
  240. {
  241. BOOL success = FALSE;
  242. struct MsgPort *VMPort;
  243.  
  244. UsageMsg->VMMessage.mn_Length = sizeof (struct VMUsageMsg);
  245. UsageMsg->Sender      = FindTask (NULL);
  246. UsageMsg->Command     = VMCMD_AskVMUsage;
  247. UsageMsg->ReplySignal = VMSignal;
  248.  
  249. Forbid ();
  250. if ((VMPort = FindPort ("VMM_Port")) != NULL)
  251.   {
  252.   PutMsg (VMPort, (struct Message*)UsageMsg);
  253.   success = TRUE;
  254.   }
  255. Permit ();
  256.  
  257. if (!success)
  258.   return (NULL);
  259.  
  260. Wait (1L << VMSignal);
  261.  
  262. return (UsageMsg->TaskList);
  263. }
  264.  
  265. /******************************************************************************/
  266.  
  267. void UpdateList (void)
  268.  
  269. {
  270. /* Updates the currently visible list. To minimize the amount
  271.  * of flickering on the screen only new, deleted  or changed entries are
  272.  * updated. To do this the list received from VMM is sorted first
  273.  * and then stepwise compared with the list currently displayed.
  274.  * As changed entries are encountered the display is changed accordingly.
  275.  */
  276.  
  277. ULONG level;
  278. struct List *UpdatedList;
  279. struct TaskVMUsage *upd_entry,
  280.                    *disp_entry;
  281. int pos;
  282.  
  283. get (ObjApp->SL_UpdateTime, MUIA_Slider_Level, &level);
  284.  
  285. AddTimedFunction (TimerData, level / 10, (level % 10) * 100000L, UpdateList);
  286.  
  287. if ((UpdatedList = GetListFromVMM ()) != NULL)
  288.   {
  289.   SortList (UpdatedList);
  290.  
  291.   pos = 0;
  292.   DoMethod (ObjApp->LV_TaskList, MUIM_List_GetEntry, pos, &disp_entry);
  293.   upd_entry = (struct TaskVMUsage*) RemHead (UpdatedList);
  294.  
  295.   while (upd_entry != NULL || disp_entry != NULL)
  296.     {
  297.     int relation;
  298.  
  299.     if (disp_entry == NULL)
  300.       relation = 1;               /* As if the entry was larger */
  301.     else if (upd_entry == NULL)
  302.       relation = -1;
  303.     else
  304.       relation = Stricmp (disp_entry->vu_Node.ln_Name, upd_entry->vu_Node.ln_Name);
  305.  
  306.     if (relation < 0)
  307.       {
  308.       /* There is an entry displayed which is not in the updated
  309.        * list anymore. Remove it.
  310.        */
  311.       DoMethod (ObjApp->LV_TaskList, MUIM_List_Remove, pos);
  312.       DoMethod (ObjApp->LV_TaskList, MUIM_List_GetEntry, pos, &disp_entry);
  313.       }
  314.     else if (relation > 0)
  315.       {
  316.       /* There is a new entry in the updated list.
  317.        * Add it to the display list.
  318.        */
  319.       DoMethod (ObjApp->LV_TaskList, MUIM_List_InsertSingle, upd_entry, pos);
  320.       pos++;
  321.       /* disp_entry remains the same */
  322.       upd_entry = (struct TaskVMUsage*)RemHead (UpdatedList);
  323.       ListEmpty = FALSE;
  324.       }
  325.     else
  326.       {
  327.       /* The entries are identical. Check if the values differ
  328.        * and do a refresh only when necessary.
  329.        */
  330.       if (disp_entry->VMInUse != upd_entry->VMInUse)
  331.         {
  332.         disp_entry->VMInUse = upd_entry->VMInUse;
  333.         DoMethod (ObjApp->LV_TaskList, MUIM_List_Redraw, pos);
  334.         }
  335.       FreeMem (upd_entry, upd_entry->FreeSize);
  336.       upd_entry = (struct TaskVMUsage*)RemHead (UpdatedList);
  337.       pos++;
  338.       DoMethod (ObjApp->LV_TaskList, MUIM_List_GetEntry, pos, &disp_entry);
  339.       }
  340.     } 
  341.  
  342.   FreeMem (UpdatedList, sizeof (struct List));
  343.   }
  344. else if (!ListEmpty)
  345.   {
  346.   DoMethod (ObjApp->LV_TaskList, MUIM_List_Clear);
  347.   ListEmpty = TRUE;
  348.   }
  349. }
  350.  
  351. /******************************************************************************/
  352.  
  353. BOOL Init (void)
  354.  
  355. {
  356. VMSignal = -1L;
  357.  
  358. if ((MUIMasterBase = OpenLibrary ("muimaster.library", 10L)) == NULL)
  359.   {
  360.   printf ("Couldn't open muimaster.library\n");
  361.   return (FALSE);
  362.   }
  363.  
  364. if ((UtilityBase = OpenLibrary ("utility.library", 10L)) == NULL)
  365.   {
  366.   printf ("Couldn't open utility.library\n");
  367.   return (FALSE);
  368.   }
  369.  
  370. if ((TimerData = InitTimer (1, &TimerSignal)) == NULL)
  371.   {
  372.   printf ("Couldn't initialize timer\n");
  373.   return (FALSE);
  374.   }
  375.  
  376. if ((UsageMsg = AllocMem (sizeof (struct VMUsageMsg), MEMF_PUBLIC)) == NULL)
  377.   {
  378.   printf ("Not enough memory\n");
  379.   return (FALSE);
  380.   }
  381.  
  382. if ((VMSignal = AllocSignal (-1L)) == -1L)
  383.   {
  384.   printf ("Ran out of signal bits\n");
  385.   return (FALSE);
  386.   }
  387.  
  388. if ((ObjApp = CreateApp ()) == NULL)
  389.   {
  390.   printf ("Couldn't create MUI application\n");
  391.   return (FALSE);
  392.   }
  393. }
  394.  
  395. /******************************************************************************/
  396.  
  397. void Cleanup (void)
  398.  
  399. {
  400. if (ObjApp)
  401.   DisposeApp (ObjApp);
  402.  
  403. if (VMSignal != -1L)
  404.   FreeSignal (VMSignal);
  405.  
  406. if (UsageMsg != NULL)
  407.   FreeMem (UsageMsg, sizeof (struct VMUsageMsg));
  408.  
  409. if (TimerData != NULL)
  410.   CloseTimer (TimerData);
  411.  
  412. if (UtilityBase != NULL)
  413.   CloseLibrary (UtilityBase);
  414.  
  415. if (MUIMasterBase != NULL)
  416.   CloseLibrary (MUIMasterBase);
  417. }
  418.  
  419. /******************************************************************************/
  420.  
  421. void main (void)
  422.  
  423. {
  424. ULONG MUISignals;
  425. BOOL running = TRUE;
  426. ULONG ReceivedSignals;
  427.  
  428. if (!Init ())
  429.   {
  430.   Cleanup ();
  431.   exit (10);
  432.   }
  433.  
  434. ReceivedSignals = 0L;
  435. AddTimedFunction (TimerData, 1L, 0L, UpdateList);
  436. UpdateList ();
  437.  
  438. while (running)
  439.   {
  440.   switch (DoMethod(ObjApp->App, MUIM_Application_Input, &MUISignals))
  441.     {
  442.     case MUIV_Application_ReturnID_Quit:
  443.          running = FALSE;
  444.          break;
  445.     }
  446.  
  447.   if (running && (MUISignals != 0L))
  448.     ReceivedSignals = Wait (MUISignals | (1L << TimerSignal));
  449.  
  450.   if (ReceivedSignals & (1L << TimerSignal))
  451.     HandleTimerReturn (TimerData);
  452.   }
  453.  
  454. Cleanup ();
  455. }
  456.